<template>
  <vxe-modal
    v-model="dialogFormVisible"
    :title="title"
    width="80%"
    show-footer
    transfer
    destroy-on-close
    @close="close"
  >
    <template #default>
      <vxe-form
        ref="formRef"
        :data="form"
        :rules="rules"
        title-align="right"
        title-width="120"
        prevent-submit
        custom-layout
        title-colon
      >
        <vxe-form-item v-if="form.parentName !== ''" title="上级菜单" span="24">
          <template #default>
            <el-input
              v-model="form.parentName"
              placeholder="请输入上级菜单"
              disabled
              style="width: 320px"
            />
          </template>
        </vxe-form-item>
        <vxe-form-item title="菜单名称" span="24" field="name">
          <template #default>
            <el-input
              v-model="form.name"
              placeholder="请输入菜单名称"
              style="width: 320px"
            />
          </template>
        </vxe-form-item>
        <vxe-form-item title="菜单类型" span="6" field="type">
          <template #default>
            <el-radio-group v-model="form.type">
              <el-radio-button
                v-for="item in menuTypeOptions"
                :key="item.key"
                :label="item.key"
              >
                {{ item.display_name }}
              </el-radio-button>
            </el-radio-group>
          </template>
        </vxe-form-item>
        <vxe-form-item
          title="菜单可见"
          span="6"
          field="visible"
          :title-prefix="{
            message: '选择隐藏时，路由将不会出现在侧边栏，但仍然可以访问',
            icon: 'vxe-icon-question-circle-fill',
          }"
        >
          <template #default>
            <el-radio-group v-model="form.visible">
              <el-radio-button :label="false">是</el-radio-button>
              <el-radio-button :label="true">否</el-radio-button>
            </el-radio-group>
          </template>
        </vxe-form-item>
        <vxe-form-item
          v-if="form.type === 2"
          title="总是显示"
          span="6"
          field="alwaysShow"
          :title-prefix="{
            message:
              '选择不是时，当该菜单只有一个子菜单时，不展示自己，直接展示子菜单',
            icon: 'vxe-icon-question-circle-fill',
          }"
        >
          <template #default>
            <el-radio-group v-model="form.alwaysShow">
              <el-radio-button :label="false">是</el-radio-button>
              <el-radio-button :label="true">否</el-radio-button>
            </el-radio-group>
          </template>
        </vxe-form-item>
        <vxe-form-item
          v-if="form.type === 2"
          title="缓存状态"
          span="6"
          field="keepAlive"
          :title-prefix="{
            message:
              '选择缓存时，则会被 `keep-alive` 缓存，必须填写「组件名称」字段',
            icon: 'vxe-icon-question-circle-fill',
          }"
        >
          <template #default>
            <el-radio-group v-model="form.keepAlive">
              <el-radio-button :label="false">缓存</el-radio-button>
              <el-radio-button :label="true">不缓存</el-radio-button>
            </el-radio-group>
          </template>
        </vxe-form-item>
        <vxe-form-item
          v-if="form.type === 2"
          title="是否固定"
          span="6"
          field="noClosable"
          :title-prefix="{
            message: '当前路由是否可关闭多标签页',
            icon: 'vxe-icon-question-circle-fill',
          }"
        >
          <template #default>
            <el-radio-group v-model="form.noClosable">
              <el-radio-button :label="true">是</el-radio-button>
              <el-radio-button :label="false">否</el-radio-button>
            </el-radio-group>
          </template>
        </vxe-form-item>
        <vxe-form-item
          v-if="form.type === 2"
          title="打开方式"
          span="6"
          field="openWith"
        >
          <template #default>
            <el-radio-group v-model="form.openWith">
              <el-radio-button label="locality">本地</el-radio-button>
              <el-radio-button label="link">外部</el-radio-button>
              <el-radio-button label="iframe">内嵌</el-radio-button>
            </el-radio-group>
          </template>
        </vxe-form-item>
        <vxe-form-item
          v-if="form.type === 2"
          title="路由路径"
          span="24"
          field="path"
          :title-prefix="{
            message:
              '访问的路由地址，如：`user`。如需外部地址时，则以 `http(s)://` 开头',
            icon: 'vxe-icon-question-circle-fill',
          }"
        >
          <template #default>
            <el-input v-model="form.path" placeholder="请输入路由路径" />
          </template>
        </vxe-form-item>
        <vxe-form-item
          v-if="form.type === 2"
          title="组件地址"
          span="12"
          field="components"
        >
          <template #default>
            <el-input
              v-model="form.component"
              placeholder="例如说：system/user/index"
            />
          </template>
        </vxe-form-item>
        <vxe-form-item
          v-if="form.type === 2"
          title="组件名字"
          span="12"
          field="componentName"
          :title-prefix="{
            message: '首字母必须大写,例如说：SystemUser',
            icon: 'vxe-icon-question-circle-fill',
          }"
        >
          <template #default>
            <el-input
              v-model="form.componentName"
              placeholder="例如说：SystemUser"
              style="width: 230px"
            />
          </template>
        </vxe-form-item>
        <vxe-form-item
          v-if="form.type !== 3"
          title="图标"
          span="24"
          field="icon"
        >
          <template #default>
            <el-popover
              popper-class="icon-selector-popper"
              trigger="hover"
              :width="350"
            >
              <template #reference>
                <el-input v-model="form.icon" style="width: 320px" />
              </template>
              <vab-icon-selector @handle-icon="handleIcon" />
            </el-popover>
          </template>
        </vxe-form-item>
        <vxe-form-item
          title="权限标识"
          span="24"
          field="permission"
          :title-prefix="{
            message:
              'Controller 方法上的权限字符，如：@PreAuthorize(`@ss.hasPermission(system:user:list)`)',
            icon: 'vxe-icon-question-circle-fill',
          }"
        >
          <template #default>
            <el-input
              v-model="form.permission"
              placeholder="请输入权限标识"
              style="width: 360px"
            />
          </template>
        </vxe-form-item>
        <vxe-form-item title="排序" span="12" field="sort">
          <template #default>
            <el-input-number
              v-model="form.sort"
              controls-position="right"
              :min="1"
              :max="1000"
              placeholder="请输入排序"
              style="width: 160px"
            />
          </template>
        </vxe-form-item>
        <vxe-form-item title="菜单状态" span="24" field="status">
          <template #default>
            <el-radio-group v-model="form.status">
              <el-radio-button :label="0">启用</el-radio-button>
              <el-radio-button :label="1">关闭</el-radio-button>
            </el-radio-group>
          </template>
        </vxe-form-item>
      </vxe-form>
    </template>
    <template #footer>
      <div class="dialog-footer" style="text-align: center">
        <el-button
          :loading="fullscreenLoading"
          class="filter-item"
          type="primary"
          @click="save()"
        >
          <i class="icon-wpkj-save"></i>
          保存
        </el-button>
        <el-button @click="close()">取消</el-button>
      </div>
    </template>
  </vxe-modal>
</template>

<script>
  import VabIconSelector from '@/plugins/VabIconSelector'
  import { isChina } from '@/utils/validate'
  import { getMenuByParentIdNextSort, saveOrUpdate } from '@/api/system/menu'

  export default defineComponent({
    name: 'MenuEdit',
    components: { VabIconSelector },
    emits: ['fetch-data'],
    setup(props, { emit }) {
      const $baseMessage = inject('$baseMessage')

      const state = reactive({
        formRef: null,
        form: {
          id: '',
          name: '',
          permission: '',
          type: 1,
          sort: 0,
          parentId: '',
          path: '',
          icon: '',
          component: '',
          componentName: '',
          status: 0,
          visible: false,
          keepAlive: true,
          alwaysShow: true,
          openWith: 'locality',
          noClosable: false,
          components: '',
        },
        rules: {
          permission: [
            {
              required: true,
              message: `请输入权限标识`,
              trigger: 'blur',
            },
            {
              min: 1,
              max: 100,
              message: '长度在 1 到 100 个字符',
              trigger: 'blur',
            },
            {
              validator({ itemValue }) {
                if (!!itemValue && isChina(itemValue)) {
                  return new Error('不能包含中文')
                }
              },
            },
          ],
          name: [
            {
              required: true,
              message: '请输入菜单名称',
              trigger: 'blur',
            },
            {
              min: 1,
              max: 25,
              message: '长度在 1 到 50 个字符',
              trigger: 'blur',
            },
          ],
          component: [
            {
              required: true,
              message: `请输入组件地址`,
              trigger: 'blur',
            },
          ],
          componentName: [
            {
              max: 200,
              message: '请输入组件名字',
              trigger: 'blur',
            },
          ],
          path: [
            {
              required: true,
              message: `请输入路径`,
              trigger: 'blur',
            },
          ],
          type: [
            {
              required: true,
              message: `请选择类型`,
              trigger: 'blur',
            },
          ],
          sort: [
            {
              required: true,
              message: `请输入排序`,
              trigger: 'blur',
            },
          ],
          status: [
            {
              required: true,
              message: `请选择菜单状态`,
              trigger: 'blur',
            },
          ],
        },
        title: '',
        dialogFormVisible: false,
        menuTypeOptions: [
          { key: 1, display_name: '目录' },
          { key: 2, display_name: '菜单' },
          { key: 3, display_name: '按钮' },
        ],
        fullscreenLoading: false,
      })

      const handleIcon = (item) => {
        state.form.icon = `ri-${item}`
      }
      const showEdit = (row, but) => {
        if (but === 'add') {
          state.title = '添加'
          if (row) {
            state.form.parentName = row.name
            state.form.parentId = row.id
          } else {
            state.form.parentName = ''
            state.form.parentId = '1'
          }
          getMenuByParentIdNextSort(row.id).then((response) => {
            state.form.sort = response.data.sort
          })
        } else {
          state.title = '编辑'
          state.form = JSON.parse(JSON.stringify(row))
        }
        state.dialogFormVisible = true
      }
      const close = () => {
        state['formRef'].reset()
        state.form = {
          id: '',
          name: '',
          permission: '',
          type: 1,
          sort: '',
          parentId: '',
          path: '',
          icon: '',
          component: '',
          componentName: '',
          status: 0,
          visible: false,
          keepAlive: true,
          alwaysShow: true,
          openWith: 'locality',
          noClosable: false,
          components: '',
        }
        state.dialogFormVisible = false
      }
      const save = async () => {
        const validate = await state['formRef']
          .validate()
          .catch((validate) => validate)

        if (!validate) {
          state.fullscreenLoading = true
          saveOrUpdate(state.form)
            .then((response) => {
              if (response.code === 0 || response.code === 200) {
                $baseMessage(response.msg, 'success')
                emit('fetch-data', response.data)
                close()
              } else {
                $baseMessage(response.msg, 'error')
              }
              state.fullscreenLoading = false
            })
            .catch(() => {
              state.fullscreenLoading = false
            })
        }
      }

      return {
        ...toRefs(state),
        handleIcon,
        showEdit,
        close,
        save,
      }
    },
  })
</script>
